package org.apache.rocketmq.console.shiro.config;

import javax.annotation.Resource;

import org.apache.rocketmq.console.config.LoginConfigure;
import org.apache.rocketmq.console.script.dao.DeptInfoDao;
import org.apache.rocketmq.console.script.model.DeptInfo;
import org.apache.rocketmq.console.shiro.entity.UserInfo;
import org.apache.rocketmq.console.shiro.entity.UserPermission;
import org.apache.rocketmq.console.shiro.entity.UumsResResult;
import org.apache.rocketmq.console.shiro.sevice.UserInfoService;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.crypto.hash.SimpleHash;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;

public class MyShiroRealm extends AuthorizingRealm {
	@Resource
	private UserInfoService userInfoService;
	@Resource
	private LoginConfigure loginConfigure;

	@Resource
	private DeptInfoDao deptInfoDao;

	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
		System.out.println("权限配置-->MyShiroRealm.doGetAuthorizationInfo()");
		UserInfo userInfo = (UserInfo) principals.getPrimaryPrincipal();

		// 3. 创建 SimpleAuthorizationInfo, 并设置其 reles 属性.
		SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
		authorizationInfo.addStringPermission(userInfo.getPermission());
		return authorizationInfo;
	}

	/* 主要是用来进行身份认证的，也就是说验证用户输入的账号和密码是否正确。 */
	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authcToken)
			throws AuthenticationException {
		UsernamePasswordToken token = (UsernamePasswordToken) authcToken;
		System.out.println("MyShiroRealm.doGetAuthenticationInfo()");
		// 获取用户的输入的账号.
		String username = token.getUsername();
		String password = String.valueOf(token.getPassword());
		UumsResResult uumsResResult = null;
		try {
			uumsResResult = loginConfigure.loginByUUMS(token);
		} catch (Exception e) {
			uumsResResult = new UumsResResult();
		}
		// final UumsResResult uumsResResult = JSON.parseObject(uumsResResultJSON,
		// UumsResResult.class);
		UserInfo userInfo = userInfoService.findByUsername(username);
		if (!"200".equals(uumsResResult.getStatusCode()) && userInfo == null) {
			return null;
		}

		if (userInfo == null && "200".equals(uumsResResult.getStatusCode())) {
			userInfo = new UserInfo();
			userInfo.setName(username);
			userInfo.setPassword(generatePwd(username, password));
			userInfo.setPermissionId(3);
			userInfo.setEmpName(uumsResResult.getResult().getEmpName());
			userInfo.setDeptCode(uumsResResult.getResult().getDeptCode());
			userInfo.setDeptName(uumsResResult.getResult().getDeptName());
			userInfoService.save(userInfo);

		}

		// 当uums用户名密码正确并且console自身的数据库也有此用户时，使用uums用户名密码登录
		if ("200".equals(uumsResResult.getStatusCode())) {
			userInfo.setPassword(generatePwd(username, password));
			userInfo.setEmpName(uumsResResult.getResult().getEmpName());
			userInfo.setDeptCode(uumsResResult.getResult().getDeptCode());
			userInfo.setDeptName(uumsResResult.getResult().getDeptName());

			DeptInfo deptInfo = deptInfoDao.findOneByCode(uumsResResult.getResult().getDeptCode());
			if (deptInfo == null) {
				deptInfo = new DeptInfo();
				deptInfo.setCode(uumsResResult.getResult().getDeptCode());
				deptInfo.setName(uumsResResult.getResult().getDeptName());
				deptInfoDao.save(deptInfo);
			}
		}

		UserPermission userPermission = userInfoService.findUserPermissionById(userInfo.getPermissionId());
		userInfo.setPermission(userPermission.getPermission());

		SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(userInfo, // 用户名
				userInfo.getPassword(), // 密码
				ByteSource.Util.bytes(userInfo.getName()), // salt=username
				getName() // realm name
		);

		return authenticationInfo;
	}

	public String generatePwd(String name, String pwd) {
		String hashAlgorithmName = "MD5";
		Object credentials = pwd;
		Object salt = ByteSource.Util.bytes(name);
		int hashIterations = 2;

		Object result = new SimpleHash(hashAlgorithmName, credentials, salt, hashIterations);
		return result.toString();
	}

}